package com.webratio.units.custom.tagcloudunit;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Element;

import com.webratio.rtx.RTXConstants;
import com.webratio.rtx.RTXContentUnitService;
import com.webratio.rtx.RTXException;
import com.webratio.rtx.RTXManager;
import com.webratio.rtx.core.AbstractService;
import com.webratio.rtx.core.BeanHelper;
import com.webratio.rtx.core.DescriptorHelper;

public class TagCloudUnitService extends AbstractService implements
		RTXContentUnitService {

	// valori predefiniti
	Integer minFontSize = 10;
	Integer maxFontSize = 36;

	protected TagCloudUnitBean getUnitBean(Map pageContext, Map sessionContext)
			throws RTXException {
		TagCloudUnitBean unitBean = (TagCloudUnitBean) pageContext
				.get('_' + getId());
		if (unitBean == null || unitBean.getDataSize() == 0) {
			unitBean = createUnitBean(pageContext, sessionContext);
		}

		// lettura dei parametri di input
		String strOids[] = BeanHelper.asStringArray(pageContext.get(getId()
				+ ".oid"));
		String strTagNames[] = BeanHelper.asStringArray(pageContext.get(getId()
				+ ".tagName"));
		String strTagCount[] = BeanHelper.asStringArray(pageContext.get(getId()
				+ ".tagCount"));

		if (strOids.length != strTagNames.length
				|| strOids.length != strTagCount.length)
			throw new RTXException("Inputs must be of the same length!");

		Tag[] tags = new Tag[strOids.length];

		Integer minTagCount = 1;
		Integer maxTagCount = 1;
		for (int i = 0; i < strOids.length; i++) {
			Integer m = 1;
			try {
				m = Integer.parseInt(strTagCount[i]);
			} catch (Exception ex) {
			}
			if (m < minTagCount)
				minTagCount = m;
			if (m > maxTagCount)
				maxTagCount = m;
		}

		for (int i = 0; i < strOids.length; i++) {
			Tag t = new Tag(minFontSize, maxFontSize, minTagCount, maxTagCount);

			try {
				t.setOid(Integer.parseInt(strOids[i]));
			} catch (Exception ex) {
			}
			try {
				t.setTagName(strTagNames[i]);
			} catch (Exception ex) {
			}
			try {
				t.setTagCount(Integer.parseInt(strTagCount[i]));
			} catch (Exception ex) {
			}

			tags[i] = t;
		}

		// inserimento nel bean dei valori letti in precedenza
		unitBean.setMinFontSize(minFontSize);
		unitBean.setMaxFontSize(maxFontSize);
		unitBean.setData(tags);
		unitBean.setDataSize(tags.length);

		// recupero dell'id corrente
		String fieldName = getId() + ".current.oid";
		HttpServletRequest request = (HttpServletRequest) pageContext
				.get(RTXConstants.HTTP_SERVLET_REQUEST_KEY);
		String queryString = request.getQueryString();

		if (queryString != null) {
			try {
				Map parameters = getUrlParameters(request.getQueryString());
				if (parameters.containsKey(fieldName)) {
					String strOid = (String) ((ArrayList<?>) parameters.get(fieldName)).get(0);
					
					if (strOid != null && strOid.length() > 0) {
						Integer oid = Integer.parseInt(strOid);
						unitBean.setOid(oid);
					}
				}
			} catch (Exception e) {
			}
		}

		pageContext.put('_' + getId(), unitBean);

		return unitBean;
	}

	protected TagCloudUnitBean createUnitBean(Map pageContext,
			Map sessionContext) throws RTXException {
		TagCloudUnitBean bean = new TagCloudUnitBean();

		bean.setDataSize(0);
		bean.setData(Collections.EMPTY_LIST);

		return bean;
	}

	public TagCloudUnitService(String id, RTXManager mgr, Element descr)
			throws RTXException {

		super(id, mgr, descr);

		// Selezioniamo l'elemento che contiene i valori della unit corrente
		Element currentUnit = descr.element("TagCloudUnit");

		// lettura parametri statici
		try {
			minFontSize = Integer.parseInt(DescriptorHelper.getAttribute(
					currentUnit, "minFontSize", true, this));
		} catch (Exception ex) {
		}
		try {
			maxFontSize = Integer.parseInt(DescriptorHelper.getAttribute(
					currentUnit, "maxFontSize", true, this));
		} catch (Exception ex) {
		}
	}

	public Object computeParameterValue(String outputParamName,
			Map pageContext, Map sessionContext) throws RTXException {

		Object unitBean = getUnitBean(pageContext, sessionContext);
		if (unitBean == null) {
			return null;
		}

		throw new RTXException("Please use normal links only.");
	}

	public Object execute(Map pageContext, Map sessionContext)
			throws RTXException {

		// inizializzazione bean
		TagCloudUnitBean unitBean = getUnitBean(pageContext, sessionContext);
		if (unitBean == null) {
			return null;
		}

		return unitBean;
	}

	public void dispose() {
		// TODO Auto-generated method stub
	}

	private static Map<String, List<String>> getUrlParameters(String query)
			throws UnsupportedEncodingException {
		
		Map<String, List<String>> params = new HashMap<String, List<String>>();

		for (String param : query.split("&")) {
			String pair[] = param.split("=");
			String key = URLDecoder.decode(pair[0], "UTF-8");
			String value = URLDecoder.decode(pair[1], "UTF-8");
			List<String> values = params.get(key);
			if (values == null) {
				values = new ArrayList<String>();
				params.put(key, values);
			}
			values.add(value);
		}

		return params;
	}
}